<?php

namespace App\Admin\Controllers;

use App\Http\Controllers\Controller;
use App\Models\Base\LogMerge;
use App\Models\Base\ServerList;
use App\Models\Game\PlayerGamedata;
use App\Service\ScriptService;
use App\Service\ServerOnlineService;
use Encore\Admin\Controllers\ModelForm;
use Encore\Admin\Exception\Handler;
use Encore\Admin\Facades\Admin;
use Encore\Admin\Form;
use Encore\Admin\Grid;
use Encore\Admin\Layout\Content;
use Illuminate\Support\Facades\DB;

class MergeController extends Controller
{
    use ModelForm;

    /**
     * Index interface.
     *
     * @return Content
     */
    public function index()
    {
        return Admin::content(function (Content $content) {
            $content->header(trans('game.merge_server'));
            $content->description(trans('admin.list'));

            $content->body($this->grid());
        });
    }

    /**
     * Create interface.
     *
     * @return Content
     */
    public function create()
    {
        return Admin::content(function (Content $content) {
            $content->header(trans('game.merge_server'));
            $content->description(trans('admin.new'));

            $content->body($this->form());
        });
    }

    /**
     * Make a grid builder.
     *
     * @return Grid
     */
    protected function grid()
    {
        return Admin::grid(LogMerge::class, function (Grid $grid) {
            $grid->id('ID')->sortable();
            $grid->from_id(trans('game.merge_by_sid'));
            $grid->to_id(trans('game.merge_sid'));
            $grid->section(trans('game.merge_interval'));
            $grid->created_at(trans('game.operating_time'));
            $grid->disableActions();
            $grid->disableRowSelector();
        });
    }

    /**
     * Make a form builder.
     *
     * @return Form
     */
    protected function form()
    {
        return Admin::form(LogMerge::class, function (Form $form) {
            $form->text('from_id', trans('game.merge_by_sid'))->rules('required|numeric');
            $form->text('to_id', trans('game.merge_sid'))->rules('required|numeric');
            $form->text('section', trans('game.merge_interval'))->rules('required|regex:/^\d+-\d+$/')->help(trans('game.sep_5'));
            $form->textarea('desc', trans('game.desc'))->rows(3);
            $form->saving(function (Form $form) {
                $form->model()->uid = Admin::user()->id;
                if (!$this->exeMerge()) {
                    return back()->withInput();
                }
            });
        });
    }

    protected function exeMerge()
    {
        $data = request()->all();
        $src_id = $data['from_id']; //被合服id
        $dest_id = $data['to_id']; //合服id
        if ($src_id === $dest_id) {
            return Handler::error(trans('admin.failed'), trans('game.merge_id_same'));
        }
        $merge_ids = explode('-', $data['section']); //合服id区间
        $count = ServerOnlineService::serverExist([$src_id, $dest_id]);
        if (!$count) {
            return Handler::error(trans('admin.failed'), trans('game.server_is_no'));
        }
        //逗号拼装区间id
        $servers = ServerList::withTrashed()->pluck('server_id')->toArray();
        for ($i = $merge_ids[0]; $i <= $merge_ids[1]; ++$i) {
            if ($i == $dest_id || !in_array($i, $servers)) {
                continue;
            }
            $param[] = $i;
        }
        $param = join(',', $param);

        $src = ScriptService::grepServer($src_id);
        $dest = ScriptService::grepServer($dest_id);
        if ($src || $dest) {
            return Handler::error(trans('admin.failed'), trans('game.close_gs'));
        }
        //查询合服进程
        if (ScriptService::mergeServer()) {
            return Handler::error(trans('admin.failed'), trans('game.merge_process'));
        }
        //执行合服
        ScriptService::exeMerge($src_id, $dest_id, $param);
        //判断是否合服成功
        sleep(3);
        setDB($src_id);
        $player_one = PlayerGamedata::orderBy('LEVEL', 'DESC')->limit(1)->first();
        setDB($dest_id);
        $player_two = DB::reconnect('mysql_game')->table('player_gamedata')->find("{$player_one->id}");
        if (!$player_two) {
            return Handler::error(trans('admin.failed'), trans('game.gs_internal_error'));
        }
        //更新已合服的物理服id
        ServerOnlineService::mergeLog($src_id, $dest_id, $data['section']);
        //删除被合的服
        ServerOnlineService::deleteServer([$src_id]);
        //更新合服标识
        ServerList::where('server_id', $dest_id)->update(['merge_tag' => $data['section'].'服']);

        return true;
    }
}
